package diandiansong.library.ui.base;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import diandiansong.library.R;


/**
 * 从BaseListAdapter继承的Adaper重写bindView即可
 * <p/>
 * setOnInViewClickListener可给内部空间添加点击事件
 *
 * @param <E>
 * @author Arroon
 */
public abstract class BaseListAdapter<E> extends BaseAdapter {

    private List<E> list;
    protected Context context;
    private LayoutInflater inflater;

    /**
     * 正对footer显示的一些状态，normal，不显示footer
     */
    public static final int STATE_NONE = 0;
    /**
     * 显示loading的footer
     */
    public static final int STATE_LOAD_MORE = 2;

    protected int state = STATE_NONE;

    public void setState(int state) {
        this.state = state;
        notifyDataSetChanged();
    }

    public int getState() {
        return this.state;
    }


    @SuppressWarnings("unused")
    private BaseListAdapter() {
    }

    public BaseListAdapter(Context context) {
        super();
        this.context = context;
        inflater = LayoutInflater.from(context);
    }

    public BaseListAdapter(Context context, List<E> list) {
        super();
        this.context = context;
        this.list = list;
        inflater = LayoutInflater.from(context);
    }

    public E getSubItem(int position, int index) {
        return null;
    }

    /**
     * 可重写getDataSize
     *
     * @return count +1
     */
    @Override
    public final int getCount() {
        if (getState() == STATE_NONE) {
            return getDataSize();
        } else {
            return getDataSize() + 1;
        }
    }

    public int getDataSize() {
        return list == null ? 0 : list.size();
    }

    @Override
    public E getItem(int position) {
        if (list.size() > position) {
            return list.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    public void setData(List<E> data) {
        if (data == null) {
            data = new ArrayList<>();
        }
        list = data;
        notifyDataSetChanged();
    }

    public List<E> getData() {
        return list == null ? (list = new ArrayList<>()) : list;
    }

    public void addAll(List<E> data) {
        if (list == null) {
            list = new ArrayList<>();
        }
        if (data != null && !data.isEmpty()) {
            list.addAll(data);
        }
        notifyDataSetChanged();
    }

    public void add(E obj) {
        if (list == null) {
            list = new ArrayList<>();
        }
        list.add(obj);
        notifyDataSetChanged();
    }

    public void add(int pos, E obj) {
        if (list != null) {
            list.add(pos, obj);
        }
        notifyDataSetChanged();
    }

    public void remove(E obj) {
        list.remove(obj);
        notifyDataSetChanged();
    }

    public void remove(int position) {
        if (list != null) {
            list.remove(position);
        }
        notifyDataSetChanged();
    }

    public void clear() {
        if (list != null) {
            list.clear();
        }
        notifyDataSetChanged();
    }

    protected abstract int getLayoutRes();

    public View getView(int position, View convertView, ViewGroup parent) {
        if (position == getCount() - 1 && getState() == STATE_LOAD_MORE) {// 最后一条
            return LayoutInflater.from(parent.getContext()).inflate(R.layout.arn_base_list_fragment_footer, null);
        }
        if (convertView == null || convertView.getTag() == null) {
            convertView = inflater.inflate(getLayoutRes(), parent, false);
        }
        bindView(position, convertView);
        if (position < list.size()) {
            // 绑定内部点击监听
            addInsideClickListener(convertView, position, list.get(position));
        } else {
            addInsideClickListener(convertView, position, null);
        }
        return convertView;
    }

    public abstract void bindView(int position, @NonNull View convertView);

    // adapter中的内部点击事件
    public Map<Integer, OnInsideClickListener> canClickItem;

    private void addInsideClickListener(final View itemV, final int position, final Object valuesMap) {
        if (canClickItem != null) {
            for (int key : canClickItem.keySet()) {
                View inView = itemV.findViewById(key);
                final OnInsideClickListener inviewListener = canClickItem.get(key);
                if (inView != null && inviewListener != null) {
                    inView.setOnClickListener(new OnClickListener() {

                        public void onClick(View v) {
                            inviewListener.onClick(itemV, v, position, valuesMap);
                        }
                    });
                }
            }
        }
    }

    /**
     * 省去频繁的findViewById
     *
     * @param view
     * @param id
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T extends View> T findViewById(View view, int id) {
        SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
        if (viewHolder == null) {
            viewHolder = new SparseArray<View>();
            view.setTag(viewHolder);
        }
        View childView = viewHolder.get(id);
        if (childView == null) {
            childView = view.findViewById(id);
            viewHolder.put(id, childView);
        }
        return (T) childView;
    }

    public void setOnInsideClickListener(int resId, OnInsideClickListener onInsideClickListener) {
        if (canClickItem == null)
            canClickItem = new HashMap<>();
        canClickItem.put(resId, onInsideClickListener);
    }

    public interface OnInsideClickListener {
        void onClick(View parentV, View v, int position, Object values);
    }

    public static void fastText(View convertView, int[] ids, String[] values) {
        for (int i = 0; i < ids.length; ++i) {
            TextView tv = findViewById(convertView, ids[i]);
            tv.setText(values[i]);
        }
    }

    public static void fastText(View convertView, int id, String value) {
        TextView tv = findViewById(convertView, id);
        tv.setText(value);
    }

    public static void fastOnClick(View convertView, int id, View.OnClickListener onClickListener) {
        View v = findViewById(convertView, id);
        v.setOnClickListener(onClickListener);
    }

    public static void fastVisibility(View convertView, int id, int visibility) {
        View v = findViewById(convertView, id);
        v.setVisibility(visibility);
    }
}
